package cn.mw.cmdb.trigger;

import cn.mw.cmdb.entity.ModelInfoFilterPropertyId;
import cn.mw.cmdb.entity.PropertyInfo;
import cn.mw.cmdb.mongoMapper.MwCmdbNotifyMapper;
import cn.mw.cmdb.mongoMapper.MwCmdbTriggerMapper;
import cn.mw.cmdb.service.impl.BaseSearchService;
import cn.mw.cmdb.trigger.service.MwCmdbTriggerService;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.components.mongodb.entity.SubCondition;
import cn.mw.microMonitorCommon.util.SpringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class MwCmdbTriggerManager extends BaseSearchService<MwCmdbNotify> implements InitializingBean, ApplicationContextAware {

    private ApplicationContext applicationContext;

    private MwCmdbNotifyMapper mwCmdbNotifyMapper;

    private MwCmdbTriggerMapper mwCmdbTriggerMapper;

    private MwCmdbTriggerService mwCmdbTriggerService;

    private ModelInfoFilterPropertyId modelInfoFilterPropertyId;

    private Map<String ,MwCmdbNotify> triggerMap = new HashMap<>();

    private static MwCmdbTriggerManager mwCmdbTriggerManager;

    public static MwCmdbTriggerManager getMwCmdbTriggerManager(){
        if(null != mwCmdbTriggerManager){
            return mwCmdbTriggerManager;
        }

        synchronized (MwCmdbTriggerManager.class){
            if(null != mwCmdbTriggerManager){
                return mwCmdbTriggerManager;
            }
            mwCmdbTriggerManager = SpringUtils.getBean(MwCmdbTriggerManager.class);
        }

        return mwCmdbTriggerManager;
    }

    public MwCmdbTriggerManager(MwCmdbNotifyMapper mwCmdbNotifyMapper ,MwCmdbTriggerMapper mwCmdbTriggerMapper
    ,MwCmdbTriggerService mwCmdbTriggerService){
        this.mwCmdbNotifyMapper = mwCmdbNotifyMapper;
        this.mwCmdbTriggerMapper = mwCmdbTriggerMapper;
        this.mwCmdbTriggerService = mwCmdbTriggerService;
        this.modelInfoFilterPropertyId = mwCmdbTriggerService.getModelInfoFilterPropertyId();
    }

    public RecordTrigger getRecordTriggerByModelName(String modelName, PropertyInfo propertyInfo){
        MwCmdbNotify mwCmdbNotify = triggerMap.get(StringSingleFieldTrigger.class.getSimpleName());
        if(null != mwCmdbNotify){
            StringSingleFieldTrigger stringSingleFieldTrigger = new StringSingleFieldTrigger(propertyInfo ,mwCmdbNotify ,mwCmdbTriggerMapper ,modelInfoFilterPropertyId);
            if(stringSingleFieldTrigger.match(modelName)){
                return stringSingleFieldTrigger;
            }
        }
        return null;
    }

    public void batchAddTrigger(List<MwCmdbTrigger> mwCmdbTriggers){
        mwCmdbTriggerMapper.insertAll(mwCmdbTriggers);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        SearchParam searchParam = new SearchParam();
        SubCondition subCondition = new SubCondition(CriteriaOpsType.is.name(), StringSingleFieldTrigger.class.getSimpleName());
        searchParam.addSubCondition(CMDBTool.getFieldName(MwCmdbNotify::getTriggerName) ,subCondition);
        Criteria criteria = genCriteria(searchParam ,true);
        List<MwCmdbNotify> list = mwCmdbNotifyMapper.find(new Query(criteria));
        if(null != list){
            for(MwCmdbNotify mwCmdbNotify: list){
                triggerMap.put(mwCmdbNotify.getTriggerName() ,mwCmdbNotify);
            }
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    protected MwCmdbNotify genObject() {
        return new MwCmdbNotify();
    }
}
